﻿using Hospital.Service;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Reflection;
using System.Text;

namespace Hospital.WebApi
{
    public static class Startup
    {
        //this关键字：在方法签名中使用this关键字意味着这个方法是一个扩展方法。
        //扩展方法允许你为现有类型添加新的方法，而无需修改其源代码或创建新的派生类型。
        //在这个例子中，AddCustomJWT方法扩展了IServiceCollection类型，
        //允许你通过services.AddCustomJWT()的方式直接在IServiceCollection实例上调用这个方法。
        public static IServiceCollection AddCustomJWT(this IServiceCollection services)
        {
            //多重lambad表达式
            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(option =>
            {
                //option可指代适合其的参数
                option.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SDMC-CJAS1-SAD-DFSFA-SADHJVF-VF-EAMF")),
                    ValidIssuer = "http://localhost:5131",
                    ValidateAudience = true,
                    ValidAudience = "http://localhost:5076",
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.FromMinutes(60)
                };
            });
            return services;
        }

        public static IServiceCollection AddApplicationServices(this IServiceCollection services)
        {
            // 获取当前程序集
            var iRepositoryAssembly = Assembly.Load("Hospital.IRepository");
            var repositoryAssembly = Assembly.Load("Hospital.Repository");
            var iServiceAssembly = Assembly.Load("Hospital.IService");
            var serviceAssembly = Assembly.Load("Hospital.Service");

            RegisterInterfacesAndImplementations(services, iRepositoryAssembly, repositoryAssembly);
            RegisterInterfacesAndImplementations(services, iServiceAssembly, serviceAssembly);

            return services;
        }

        public static void RegisterInterfacesAndImplementations(IServiceCollection services, Assembly interfaceAssembly, Assembly implementationAssembly)
        {
            // 获取接口程序集的所有接口
            var interfaces = interfaceAssembly.GetTypes()
                .Where(t => t.IsInterface);

            // 获取程序集中的所有类
            var implementations = implementationAssembly.GetTypes()
                .Where(t => t.IsClass && !t.IsAbstract);

            // 遍历接口和实现类，注册匹配的项
            foreach (var @interface in interfaces)
            {
                var implementation = implementations.FirstOrDefault(impl =>
                @interface.IsAssignableFrom(impl) && //实现类实现了接口
                //impl.Name == @interface.Name.Substring(1)); //实现类名称与接口名称匹配
                impl.Name == @interface.Name[1..]); //实现类名称与接口名称匹配

                if (implementation != null)
                {
                    services.AddScoped(@interface, implementation);
                }
            }
        }
    }
}
